use serde::Deserialize;
use std::env;
use std::fs;
use std::os::windows::process::CommandExt;
use std::process::{exit, Command};
// use std::time::Duration;
// use tokio::time::sleep;
use winapi::um::winbase::DETACHED_PROCESS;

#[derive(Debug, Deserialize)]
struct MairadbConfig {
    mariadb: MariaDetails,
    // test: Option<MariaTest>,
}

#[derive(Debug, Deserialize)]
struct MariaDetails {
    location: String,
    config_file: String,
    init: Installation,
}
#[derive(Debug, Deserialize)]
struct MariaTest {
    uri: String,
}

#[derive(Debug, Deserialize)]
struct Installation {
    data_dir: String,
}

#[tokio::main]
async fn main() {
    let maria_config = load_config("config.toml").expect("加载配置失败");

    // 获取命令行参数
    let args: Vec<String> = env::args().collect();
    if args.len() != 2 {
        eprintln!("用法: maria [start|stop|init]");
        exit(1);
    }

    let command = &args[1];
    println!("命令: {:?}", &maria_config.mariadb);

    match command.as_str() {
        "start" => {
            start_maria(
                &maria_config.mariadb.location,
                &maria_config.mariadb.config_file,
            )
            .await
        }
        "init" => {
            init(
                &maria_config.mariadb.location,
                &maria_config.mariadb.init.data_dir,
            );
        }
        "stop" => stop_mariadb(&maria_config.mariadb.location).await,
        _ => {
            eprintln!("无效的命令: {}，请使用 'start' 或 'stop'", command);
            exit(1);
        }
    }
}

fn load_config(filename: &str) -> Result<MairadbConfig, Box<dyn std::error::Error>> {
    let config_str = fs::read_to_string(filename)?;
    let maria_config: MairadbConfig = toml::de::from_str(&config_str)?;
    Ok(maria_config)
}

fn init(location: &str, data_dir: &str) {
    match fs::File::create(data_dir) {
        Ok(_) => println!("创建数据目录成功"),
        Err(e) => panic!("创建数据目录失败: {}", e),
    }

    let child = Command::new("cmd")
        .args(&[
            "/C",
            "start",
            &format!("{}\\bin\\mariadb-install-db.exe", location).to_owned(),
            "--config=G:\\Alelx\\Project\\scripts\\mariadb_scripts\\mariadb.cnf",
        ])
        .spawn()
        .expect("初始化失败");

    println!("初始化数据库中...进程ID: {}", child.id());
}

#[cfg(windows)]
async fn start_maria(location: &str, config_file: &str) {
    println!("启动MariaDB...");

    let child = Command::new(format!("{}\\bin\\mariadbd.exe", location))
        .arg(format!("--defaults-file={}", config_file))
        .creation_flags(DETACHED_PROCESS) // 使用DETACHED_PROCESS标志，使其脱离父进程
        .spawn()
        .expect("启动MariaDB失败");

    println!("MariaDB已在后台启动，进程ID: {}", child.id());
}

#[cfg(windows)]
async fn stop_mariadb(location: &str) {
    let _ = Command::new("cmd")
        .args(&[
            "/C",
            "start",
            &format!("{}\\bin\\mariadb-admin", location).to_owned(),
            "shutdown",
            "-u",
            "root",
        ])
        .spawn()
        .expect("停止MariaDB失败");
}
